import { Cartesian3, Cartographic, Math as CesiumMath } from "cesium";
import * as Cesium from "cesium";
import type { IWCS, IWGS, } from "../interfaces/entity";
/**
 * CesiumUtils 类提供了一系列 Cesium 相关的工具方法
 * 包括坐标转换、距离计算等常用功能
 * @class
 */
export class CesiumUtils {
  /**
   * 将经纬度转换为笛卡尔坐标
   * @param longitude 经度
   * @param latitude 纬度
   * @param height 高度
   * @returns 笛卡尔坐标
   */
  public static lonLatToCartesian(
    longitude: number,
    latitude: number,
    height: number = 0
  ): Cartesian3 {
    return Cartesian3.fromDegrees(longitude, latitude, height);
  }
  // private static readonly wgs84Ellipsoid = Cesium.Ellipsoid.WGS84;

  /**
   * WGS84 → 世界坐标系
   */
  static wgs84ToWorld(coord: IWGS): Cartesian3 {
    const cartesian = Cesium.Cartesian3.fromDegrees(
      coord.lon,
      coord.lat,
      coord.alt
    );
    return cartesian;
  }

  /**
   * 世界坐标系 → WGS84
   */
  static worldToWgs84(coord: IWCS | Cartesian3): IWGS {
    const carto = Cesium.Cartographic.fromCartesian(
      new Cesium.Cartesian3(coord.x, coord.y, coord.z)
    );
    return {
      lon: Cesium.Math.toDegrees(carto.longitude),
      lat: Cesium.Math.toDegrees(carto.latitude),
      alt: carto.height,
    };
  }

  /**
   * 计算两点间地表距离（考虑椭球体曲率）
   */
  static calculateSurfaceDistance(start: IWGS, end: IWGS): number {
    const geodesic = new Cesium.EllipsoidGeodesic(
      Cesium.Cartographic.fromDegrees(start.lon, start.lat),
      Cesium.Cartographic.fromDegrees(end.lon, end.lat)
    );
    return geodesic.surfaceDistance;
  }
  /**
   * 将笛卡尔坐标转换为经纬度
   * @param cartesian 笛卡尔坐标
   * @returns 经纬度
   */
  public static cartesianToLonLat(cartesian: Cartesian3): {
    longitude: number;
    latitude: number;
    height: number;
  } {
    const cartographic = Cartographic.fromCartesian(cartesian);
    return {
      longitude: CesiumMath.toDegrees(cartographic.longitude),
      latitude: CesiumMath.toDegrees(cartographic.latitude),
      height: cartographic.height,
    };
  }

  /**
   * 计算两点之间的距离（米）
   * @param point1 点1
   * @param point2 点2
   * @returns 距离（米）
   */
  public static distance(point1: Cartesian3, point2: Cartesian3): number {
    return Cartesian3.distance(point1, point2);
  }
}
